using System;
using System.Windows;
using System.Windows.Threading;
using Chambills.Present.Core;

namespace Present.Commands.Async.Actions.Decorators
{
    /// <summary>
    /// Allows for state transitions during command lifecycle
    /// </summary>
    public class SuccessVisualStateTransitionActionDecorator<TParameter, TResult> : AsyncActionDecorator<TParameter, TResult>
    {
        private readonly Dispatcher guiDispatcher;
        private readonly IPresentVisualStateManager statemanager;
        private readonly IViewRegistry viewRegistry;
        private readonly IViewModel viewModel;
        private readonly string state;
        private readonly Action<TResult> afterTransistion;

        public SuccessVisualStateTransitionActionDecorator(IAsyncAction<TParameter, TResult> innerTarget, Dispatcher guiDispatcher, IPresentVisualStateManager statemanager, IViewRegistry viewRegistry, IViewModel viewModel, string state, Action<TResult> afterTransistion) : base(innerTarget)
        {
            this.guiDispatcher = guiDispatcher;
            this.statemanager = statemanager;
            this.viewRegistry = viewRegistry;
            this.viewModel = viewModel;
            this.state = state;
            this.afterTransistion = afterTransistion;
        }

        public override void HandleSuccess(TResult result)
        {
            base.HandleSuccess(result);
            guiDispatcher.Invoke(new Action(() => ChangeState(result)), DispatcherPriority.Loaded);
        }

        private void ChangeState(TResult result)
        {
            var view = viewRegistry.FindViewFor((object)viewModel ?? result) as FrameworkElement;
            if(view != null)
                statemanager.ChangeState(view, state, () => afterTransistion(result));
        }
    }
}
